home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / By the Book / Mac C Primer V2 / 5.1 - FormEdit / FormEdit.c next >
C/C++ Source or Header  |  1992-02-10  |  24KB  |  1,143 lines

  1. /************************************************************/
  2. /*                                                            */
  3. /*    FormEdit Code from Chapter Five of                        */
  4. /*                                                            */
  5. /*        *** The Macintosh Programming Primer ***            */
  6. /*                                                            */
  7. /*    Copyright 1990, Dave Mark                                */
  8. /*                                                            */
  9. /*    This program demonstrates specific Mac programming        */
  10. /*    techniques.                                                */
  11. /*                                                            */
  12. /************************************************************/
  13.  
  14. /********************/
  15. /*        MENUs        */
  16. /********************/
  17.  
  18. #define APPLE_MENU_ID        400
  19. #define A_ABOUT_ITEM        1
  20.  
  21. #define FILE_MENU_ID        401
  22. #define F_NEW_ITEM            1
  23. #define F_CLOSE_ITEM        2
  24. #define F_QUIT_ITEM            3
  25.  
  26. #define EDIT_MENU_ID        402
  27. #define E_UNDO_ITEM            1
  28. #define E_CUT_ITEM            3
  29. #define E_COPY_ITEM            4
  30. #define E_PASTE_ITEM        5
  31. #define E_CLEAR_ITEM        6
  32.  
  33.  
  34. /********************/
  35. /*     Window Types    */
  36. /********************/
  37.  
  38. #define NIL_WINDOW            0
  39. #define UNKNOWN_WINDOW        1
  40. #define DA_WINDOW            2
  41. #define FORM_WINDOW            3
  42.  
  43.  
  44. /********************/
  45. /*        ALRTs        */
  46. /********************/
  47.  
  48. #define ABOUT_ALERT            400
  49. #define ERROR_ALERT_ID        401
  50.  
  51.  
  52. /********************/
  53. /*      Error STRs    */
  54. /********************/
  55.  
  56. #define NO_MBAR                BASE_RES_ID
  57. #define NO_MENU                BASE_RES_ID+1
  58. #define NO_WIND                BASE_RES_ID+2
  59.  
  60.  
  61. /********************/
  62. /*       TextEdit        */
  63. /********************/
  64.  
  65. #define TE_NAME_AREA    0
  66. #define TE_MISC_AREA    1
  67.  
  68. #define TE_ENTER_KEY        3
  69. #define TE_DELETE_CHAR        8
  70. #define TE_TAB_CHAR            9
  71. #define TE_CARRIAGE_RETURN    13
  72.  
  73.  
  74. /************************/
  75. /*    General Defines        */
  76. /************************/
  77.  
  78. #define BASE_RES_ID            400
  79. #define NIL_POINTER            0L
  80. #define MOVE_TO_FRONT        (WindowPtr)-1L
  81. #define REMOVE_ALL_EVENTS    0
  82.  
  83. #define DRAG_THRESHOLD        30
  84.  
  85. #define WINDOW_HOME_LEFT    5
  86. #define WINDOW_HOME_TOP        45
  87. #define NEW_WINDOW_OFFSET    20
  88.  
  89. #define MIN_SLEEP            0L
  90. #define NIL_MOUSE_REGION    0L
  91.  
  92. #define LEAVE_WHERE_IT_IS    FALSE
  93.  
  94. #define WNE_TRAP_NUM        0x60
  95. #define UNIMPL_TRAP_NUM        0x9F
  96. #define SUSPEND_RESUME_BIT    0x0001
  97. #define RESUMING            1
  98.  
  99. #define NIL_STRING            "\p"
  100. #define UNTITLED_STRING        "\p<Untitled>"
  101. #define VISIBLE                TRUE
  102. #define HOPELESSLY_FATAL_ERROR    "\pGame over, man!"
  103.  
  104.  
  105. /************************/
  106. /*      Useful Macros        */
  107. /************************/
  108.  
  109. #define TopLeft( myRect )    (* (Point *) &(myRect.top) )
  110. #define BotRight( myRect )    (* (Point *) &(myRect.bottom) )
  111.  
  112.  
  113. /************************/
  114. /*        Typedefs        */
  115. /************************/
  116.  
  117. typedef    struct
  118. {
  119.     WindowRecord    w;
  120.     int                wType;
  121.     ControlHandle    vScroll;
  122.     TEHandle        nameTE, miscTE, curTE;
  123. } FormRecord, *FormPeek;
  124.  
  125.  
  126. /************************/
  127. /*         Globals        */
  128. /************************/
  129.  
  130. Boolean            gDone, gWNEImplemented, gInBackground;
  131. EventRecord        gTheEvent;
  132. MenuHandle        gAppleMenu,
  133.                 gFileMenu,
  134.                 gEditMenu;
  135. int                gNewWindowLeft = WINDOW_HOME_LEFT,
  136.                 gNewWindowTop = WINDOW_HOME_TOP;
  137. Rect            gNameRect = { 3, 43, 19, 250 },
  138.                 gMiscRect = { 22, 43, 150, 231 },
  139.                 gScrollBarRect = { 22, 234, 150, 250 };
  140.  
  141.  
  142. /************************/
  143. /*        Routines        */
  144. /************************/
  145.  
  146. void            AdjustCursor( Point mouse, RgnHandle region );
  147. void            AdjustMenus( void );
  148. void            AdjustScrollBar( FormPeek form );
  149. void            CommonAction( ControlHandle    control, short *amount );
  150. void            CreateWindow( void );
  151. void            DoActivate( WindowPtr window, Boolean becomingActive );
  152. void            DoCloseWindow( WindowPtr window );
  153. void            DoContentClick( WindowPtr window, Point mouse );
  154. void            DoIdle( void );
  155. void            DoTEKey( char c );
  156. void            DoUpdate( WindowPtr window );
  157. void            DrawForm( WindowPtr window );
  158. void            ErrorHandler( int stringNum );
  159. void            HandleAppleChoice( int theItem );
  160. void            HandleEditChoice( int theItem );
  161. void            HandleEvent( void );
  162. void            HandleFileChoice( int theItem );
  163. void            HandleMenuChoice( long int menuChoice );
  164. void            HandleMouseDown( void );
  165. void            MainLoop( void );
  166. void            MenuBarInit( void );
  167. pascal Boolean    NewClikLoop( void );
  168. void            StartTextEdit( FormPeek form );
  169. void            SwitchToNewArea( FormPeek form, int newArea );
  170. void            ToolBoxInit( void );
  171. void            TurnOffTextArea( FormPeek form, int whichArea );
  172. void            TurnOnTextArea( FormPeek form, int whichArea );
  173. pascal void        VActionProc( ControlHandle control, int part );
  174. int                WindowType( WindowPtr window );
  175.  
  176.  
  177.  
  178. /******************************** main *********/
  179.  
  180. main()
  181. {
  182.     ToolBoxInit();
  183.     MenuBarInit();
  184.  
  185.     MainLoop();
  186. }
  187.  
  188.  
  189. /*********************************** ToolBoxInit */
  190.  
  191. void    ToolBoxInit()
  192. {
  193.     InitGraf( &thePort );
  194.     InitFonts();
  195.     FlushEvents( everyEvent, REMOVE_ALL_EVENTS );
  196.     InitWindows();
  197.     InitMenus();
  198.     TEInit();
  199.     InitDialogs( NIL_POINTER );
  200.     InitCursor();
  201. }
  202.  
  203.  
  204. /***********************************    MenuBarInit    */
  205.  
  206. void    MenuBarInit()
  207. {
  208.     Handle        myMenuBar;
  209.  
  210.     if ( ( myMenuBar = GetNewMBar( BASE_RES_ID ) ) == NIL_POINTER )
  211.         ErrorHandler( NO_MBAR );
  212.     SetMenuBar( myMenuBar );
  213.     
  214.     if ( ( gAppleMenu = GetMHandle( APPLE_MENU_ID ) ) == NIL_POINTER )
  215.         ErrorHandler( NO_MENU );
  216.     AddResMenu( gAppleMenu, 'DRVR' );
  217.         
  218.     if ( ( gFileMenu = GetMHandle( FILE_MENU_ID ) ) == NIL_POINTER )
  219.         ErrorHandler( NO_MENU );
  220.         
  221.     if ( ( gEditMenu = GetMHandle( EDIT_MENU_ID ) ) == NIL_POINTER )
  222.         ErrorHandler( NO_MENU );
  223.         
  224.     DrawMenuBar();
  225. }
  226.  
  227.  
  228. /******************************** MainLoop *********/
  229.  
  230. void    MainLoop()
  231. {
  232.     RgnHandle    cursorRgn;
  233.     Boolean        gotEvent;
  234.     
  235.     gDone = FALSE;
  236.     gInBackground = FALSE;
  237.     
  238.     cursorRgn = NewRgn();
  239.     
  240.     gWNEImplemented = ( NGetTrapAddress( WNE_TRAP_NUM, ToolTrap ) !=
  241.                         NGetTrapAddress( UNIMPL_TRAP_NUM, ToolTrap ) );
  242.     while ( gDone == FALSE )
  243.     {
  244.         if ( gWNEImplemented )
  245.             gotEvent = WaitNextEvent( everyEvent, &gTheEvent, MIN_SLEEP, cursorRgn );
  246.         else
  247.         {
  248.             SystemTask();
  249.             gotEvent = GetNextEvent( everyEvent, &gTheEvent );
  250.         }
  251.         
  252.         AdjustCursor( gTheEvent.where, cursorRgn );
  253.         
  254.         if ( gotEvent )
  255.             HandleEvent();
  256.         else
  257.             DoIdle();
  258.     }
  259. }
  260.  
  261.  
  262. /************************************* HandleEvent     */
  263.  
  264. void    HandleEvent()
  265. {
  266.     char        c;
  267.     
  268.     switch ( gTheEvent.what )
  269.     {
  270.         case nullEvent:
  271.             DoIdle();
  272.             break;
  273.         case mouseDown: 
  274.             HandleMouseDown();
  275.             break;
  276.         case keyDown:
  277.         case autoKey:
  278.             c = gTheEvent.message & charCodeMask;
  279.             if (( gTheEvent.modifiers & cmdKey ) != 0) 
  280.             {
  281.                 AdjustMenus();
  282.                 HandleMenuChoice( MenuKey( c ) );
  283.             }
  284.             else
  285.                 DoTEKey( c );
  286.             break;
  287.         case activateEvt:
  288.             DoActivate( (WindowPtr)gTheEvent.message, (gTheEvent.modifiers & activeFlag) != 0 );
  289.             break;
  290.         case updateEvt:
  291.             DoUpdate( (WindowPtr)gTheEvent.message );
  292.             break;
  293.         case app4Evt:
  294.             if ( ( gTheEvent.message & SUSPEND_RESUME_BIT ) == RESUMING )
  295.             {
  296.                 gInBackground = (gTheEvent.message & 0x01) == 0;
  297.                 DoActivate(FrontWindow(), !gInBackground);
  298.             }
  299.             else
  300.                 DoIdle();
  301.             break;
  302.     }
  303. }
  304.  
  305.  
  306. /************************************* DoTEKey     */
  307.  
  308. void    DoTEKey( c )
  309. char    c;
  310. {
  311.     WindowPtr        window;
  312.     FormPeek        form;
  313.     int                wType, length, i;
  314.     CharsHandle        text;
  315.     Str255            tempStr;
  316.     
  317.     window = FrontWindow();
  318.     wType = WindowType( window );
  319.     
  320.     if ( wType == FORM_WINDOW )
  321.     {
  322.         form = (FormPeek)window;
  323.         
  324.         if ( c == TE_TAB_CHAR )
  325.         {
  326.             if ( form->curTE == form->nameTE )
  327.                 SwitchToNewArea( form, TE_MISC_AREA );
  328.             else
  329.             {
  330.                 SwitchToNewArea( form, TE_NAME_AREA );
  331.                 TESetSelect( 0, 32767, form->curTE );
  332.             }
  333.         }
  334.         else
  335.         {
  336.             TEKey( c, form->curTE );
  337.             if ( form->curTE == form->nameTE )
  338.             {
  339.                 length = (*form->nameTE)->teLength;
  340.                 if ( length == 0 )
  341.                     SetWTitle( window, UNTITLED_STRING );
  342.                 else
  343.                 {
  344.                     text = TEGetText( form->nameTE );
  345.                     tempStr[ 0 ] = length;
  346.                     for ( i=0; ( (i<length) && (i<256) ); i++ )
  347.                     {
  348.                         tempStr[ i+1 ] = (*(char **)text)[ i ];
  349.                     }
  350.                     SetWTitle( window, tempStr );
  351.                 }
  352.             }
  353.             else
  354.                 AdjustScrollBar( form );
  355.         }
  356.     }
  357. }
  358.  
  359.  
  360. /************************************* DoIdle     */
  361.  
  362. void    DoIdle()
  363. {
  364.     WindowPtr    window;
  365.     int            wType;
  366.  
  367.     window = FrontWindow();
  368.     wType = WindowType( window );
  369.     
  370.     if ( wType == FORM_WINDOW )
  371.         TEIdle( ((FormPeek)window)->curTE );
  372. }
  373.  
  374.  
  375. /************************************* HandleMouseDown */
  376.  
  377. void    HandleMouseDown()
  378. {
  379.     WindowPtr    window;
  380.     short int    thePart;
  381.     long int    menuChoice, windSize;
  382.     
  383.     thePart = FindWindow( gTheEvent.where, &window );
  384.     switch ( thePart )
  385.     {
  386.         case inMenuBar:
  387.             AdjustMenus();
  388.             menuChoice = MenuSelect( gTheEvent.where );
  389.             HandleMenuChoice( menuChoice );
  390.             break;
  391.         case inSysWindow: 
  392.             SystemClick( &gTheEvent, window );
  393.             break;
  394.         case inContent:
  395.             if ( window != FrontWindow() )
  396.             {
  397.                 SelectWindow(window);
  398.             }
  399.             else
  400.                 DoContentClick( window, gTheEvent.where );
  401.             break;
  402.         case inDrag: 
  403.             DragWindow( window, gTheEvent.where, &(screenBits.bounds) );
  404.             break;
  405.         case inGoAway:
  406.             if ( TrackGoAway(window, gTheEvent.where) )
  407.                 DoCloseWindow( window );
  408.             break;
  409.     }
  410. }
  411.  
  412.  
  413. /************************************* DoCloseWindow */
  414.  
  415. void    DoCloseWindow( window )
  416. WindowPtr    window;
  417. {
  418.     HideWindow( window );
  419.     DisposeControl( ((FormPeek)window)->vScroll );
  420.     TEDispose( ((FormPeek)window)->nameTE );
  421.     TEDispose( ((FormPeek)window)->miscTE );
  422.     CloseWindow( window );
  423.     DisposPtr( (Ptr)window );
  424. }
  425.  
  426.  
  427. /************************************* AdjustMenus */
  428.  
  429. void    AdjustMenus()
  430. {
  431.     WindowPtr    window;
  432.     int            wType;
  433.     long        offset;
  434.     TEHandle    te;
  435.     
  436.     window = FrontWindow();
  437.     wType = WindowType( window );
  438.     
  439.     if ( window == NIL_POINTER )
  440.     {
  441.         DisableItem( gFileMenu, F_CLOSE_ITEM );
  442.         
  443.         DisableItem( gEditMenu, E_UNDO_ITEM );
  444.         DisableItem( gEditMenu, E_CUT_ITEM );
  445.         DisableItem( gEditMenu, E_COPY_ITEM );
  446.         DisableItem( gEditMenu, E_PASTE_ITEM );
  447.         DisableItem( gEditMenu, E_CLEAR_ITEM );
  448.     }
  449.     else if ( wType == DA_WINDOW )
  450.     {
  451.         DisableItem( gFileMenu, F_CLOSE_ITEM );
  452.         
  453.         EnableItem( gEditMenu, E_UNDO_ITEM );
  454.         EnableItem( gEditMenu, E_CUT_ITEM );
  455.         EnableItem( gEditMenu, E_COPY_ITEM );
  456.         EnableItem( gEditMenu, E_PASTE_ITEM );
  457.         EnableItem( gEditMenu, E_CLEAR_ITEM );
  458.     }
  459.     else if ( wType == FORM_WINDOW )
  460.     {
  461.         EnableItem( gFileMenu, F_CLOSE_ITEM );
  462.         
  463.         DisableItem( gEditMenu, E_UNDO_ITEM );
  464.         DisableItem( gEditMenu, E_CUT_ITEM );
  465.         DisableItem( gEditMenu, E_COPY_ITEM );
  466.         DisableItem( gEditMenu, E_PASTE_ITEM );
  467.         DisableItem( gEditMenu, E_CLEAR_ITEM );
  468.         
  469.         te = ((FormPeek)window)->curTE;
  470.         if ( (*te)->selStart < (*te)->selEnd )
  471.         {
  472.             EnableItem( gEditMenu, E_CUT_ITEM );
  473.             EnableItem( gEditMenu, E_COPY_ITEM );
  474.             EnableItem( gEditMenu, E_CLEAR_ITEM );
  475.         }
  476.         if ( GetScrap( NIL_POINTER, 'TEXT', &offset)  > 0 )
  477.             EnableItem( gEditMenu, E_PASTE_ITEM );
  478.     }
  479. }
  480.  
  481.  
  482. /************************************* WindowType */
  483.  
  484. int    WindowType( window )
  485. WindowPtr    window;
  486. {
  487.     if ( window == NIL_POINTER )
  488.         return( NIL_WINDOW );
  489.  
  490.     if ( ((WindowPeek)window)->windowKind < 0 )
  491.         return( DA_WINDOW );
  492.     
  493.     if ( ((FormPeek)window)->wType == FORM_WINDOW )
  494.         return( FORM_WINDOW );
  495.     
  496.     return( UNKNOWN_WINDOW );
  497. }
  498.  
  499.  
  500. /************************************* HandleMenuChoice */
  501.  
  502. void    HandleMenuChoice( menuChoice )
  503. long int    menuChoice;
  504. {
  505.     int    theMenu;
  506.     int    theItem;
  507.     
  508.     if ( menuChoice != 0 )
  509.     {
  510.         theMenu = HiWord( menuChoice );
  511.         theItem = LoWord( menuChoice );
  512.         switch ( theMenu )
  513.         {
  514.             case APPLE_MENU_ID :
  515.                 HandleAppleChoice( theItem );
  516.                 break;
  517.             case FILE_MENU_ID :
  518.                 HandleFileChoice( theItem );
  519.                 break;
  520.             case EDIT_MENU_ID :
  521.                 HandleEditChoice( theItem );
  522.         }
  523.         HiliteMenu( 0 );
  524.     }
  525. }
  526.  
  527.  
  528. /********************************    HandleAppleChoice    *******/
  529.  
  530. void    HandleAppleChoice( theItem )
  531. int    theItem;
  532. {
  533.     Str255        accName;
  534.     int            accNumber;
  535.     
  536.     switch ( theItem )
  537.     {
  538.         case A_ABOUT_ITEM : 
  539.             NoteAlert( ABOUT_ALERT, NIL_POINTER );
  540.             break;
  541.         default :
  542.             GetItem( gAppleMenu, theItem, accName );
  543.             accNumber = OpenDeskAcc( accName );
  544.             break;
  545.     }
  546. }
  547.  
  548.  
  549. /********************************    HandleFileChoice    *******/
  550.  
  551. void    HandleFileChoice( theItem )
  552. int    theItem;
  553. {
  554.     WindowPtr    window;
  555.     switch ( theItem )
  556.     {
  557.         case F_NEW_ITEM :
  558.             CreateWindow();
  559.             break;
  560.         case F_CLOSE_ITEM :
  561.             if ( ( window = FrontWindow() ) != NIL_POINTER )
  562.                 DoCloseWindow( window );
  563.             break;
  564.         case F_QUIT_ITEM :
  565.             gDone = TRUE;
  566.             break;
  567.     }
  568. }
  569.  
  570.  
  571. /********************************    HandleEditChoice    *******/
  572.  
  573. void    HandleEditChoice( theItem )
  574. int    theItem;
  575. {
  576.     TEHandle    te;
  577.     WindowPtr    window;
  578.     int            wType, length, i;
  579.     CharsHandle    text;
  580.     Str255        tempStr;
  581.     FormPeek    form;
  582.     
  583.     if ( ! SystemEdit( theItem - 1 ) )
  584.     {
  585.         window = FrontWindow();
  586.         wType = WindowType( window );
  587.         
  588.         if ( wType == FORM_WINDOW )
  589.         {
  590.             form = (FormPeek)window;
  591.             te = form->curTE;
  592.             switch ( theItem )
  593.             {
  594.                 case E_UNDO_ITEM:
  595.                     break;
  596.                 case E_CUT_ITEM:
  597.                     if ( ZeroScrap() == noErr )
  598.                     {
  599.                         TECut(te);
  600.                         AdjustScrollBar( form );
  601.                         if ( TEToScrap() != noErr )
  602.                             ZeroScrap();
  603.                     }
  604.                     break;
  605.                 case E_COPY_ITEM:
  606.                     if ( ZeroScrap() == noErr )
  607.                     {
  608.                         TECopy(te);
  609.                         if ( TEToScrap() != noErr )
  610.                             ZeroScrap();
  611.                     }
  612.                     break;
  613.                 case E_PASTE_ITEM:
  614.                     if ( TEFromScrap() == noErr )
  615.                     {
  616.                         TEPaste(te);
  617.                         AdjustScrollBar( form );
  618.                     }
  619.                     break;
  620.                 case E_CLEAR_ITEM:
  621.                     TEDelete(te);
  622.                     AdjustScrollBar( form );
  623.                     break;
  624.             }
  625.             
  626.             if ( te == form->nameTE )
  627.             {
  628.                 length = (*form->nameTE)->teLength;
  629.                 if ( length == 0 )
  630.                     SetWTitle( window, UNTITLED_STRING );
  631.                 else
  632.                 {
  633.                     text = TEGetText( form->nameTE );
  634.                     tempStr[ 0 ] = length;
  635.                     for ( i=0; ( (i<length) && (i<256) ); i++ )
  636.                     {
  637.                         tempStr[ i+1 ] = (*(char **)text)[ i ];
  638.                     }
  639.                     SetWTitle( window, tempStr );
  640.                 }
  641.             }
  642.             
  643.         }
  644.     }
  645. }
  646.  
  647.  
  648. /********************************    DoContentClick    *******/
  649.  
  650. void    DoContentClick( window, mouse )
  651. WindowPtr    window;
  652. Point        mouse;
  653. {
  654.     int                wType, value;
  655.     int                thePart;
  656.     Boolean            shiftDown;
  657.     Point            locMouse;
  658.     ControlHandle    control;
  659.     FormPeek        form;
  660.     
  661.     wType = WindowType( window );
  662.     
  663.     if ( wType == FORM_WINDOW )
  664.     {
  665.         form = (FormPeek)window;
  666.         locMouse = mouse;
  667.         GlobalToLocal( &locMouse );
  668.         
  669.         if ( ( thePart = FindControl( locMouse, window, &control ) ) != 0 )
  670.         {
  671.             switch( thePart )
  672.             {
  673.                 case inUpButton:
  674.                 case inDownButton:
  675.                 case inPageUp:
  676.                 case inPageDown:
  677.                     value = TrackControl( control, locMouse, (ProcPtr) VActionProc );
  678.                     break;
  679.                 case inThumb:
  680.                     value = GetCtlValue( control );
  681.                     thePart = TrackControl( control, locMouse, NIL_POINTER );
  682.                     if ( thePart != 0 )
  683.                     {
  684.                         value -= GetCtlValue( control );
  685.                         if ( value != 0 )
  686.                             TEScroll(0, value * (*form->curTE)->lineHeight, form->miscTE );
  687.                     }
  688.                     break;
  689.             }
  690.         }
  691.         else if ( PtInRect( locMouse, &gNameRect ) )
  692.         {
  693.             if ( form->curTE == form->nameTE )
  694.             {
  695.                 shiftDown = ( gTheEvent.modifiers & shiftKey) != 0;
  696.                 TEClick( locMouse, shiftDown, form->nameTE );
  697.             }
  698.             else
  699.             {
  700.                 SwitchToNewArea( form, TE_NAME_AREA );
  701.                 TEClick( locMouse, FALSE, form->nameTE );
  702.             }
  703.         }
  704.         else if ( PtInRect( locMouse, &gMiscRect ) )
  705.         {
  706.             if ( form->curTE == form->miscTE )
  707.             {
  708.                 shiftDown = ( gTheEvent.modifiers & shiftKey) != 0;
  709.                 TEClick( locMouse, shiftDown, form->miscTE );
  710.             }
  711.             else
  712.             {
  713.                 SwitchToNewArea( form, TE_MISC_AREA );
  714.                 TEClick( locMouse, FALSE, form->miscTE );
  715.             }
  716.         }
  717.     }
  718. }
  719.  
  720.  
  721. /************************************* VActionProc */
  722.  
  723. pascal void    VActionProc(control, part)
  724. ControlHandle    control;
  725. int                part;
  726. {
  727.     short        amount;
  728.     WindowPtr    window;
  729.     TEPtr        te;
  730.     
  731.     if ( part != 0 )
  732.     {
  733.         window = (*control)->contrlOwner;
  734.         te = *((FormPeek)window)->miscTE;
  735.         switch ( part ) {
  736.             case inUpButton:
  737.             case inDownButton:        /* one line */
  738.                 amount = 1;
  739.                 break;
  740.             case inPageUp:            /* one page */
  741.             case inPageDown:
  742.                 amount = (te->viewRect.bottom - te->viewRect.top) / te->lineHeight;
  743.                 break;
  744.         }
  745.         if ( (part == inDownButton) || (part == inPageDown) )
  746.             amount = -amount;
  747.         CommonAction(control, &amount);
  748.         if ( amount != 0 )
  749.             TEScroll( 0, amount * te->lineHeight, ((FormPeek)window)->miscTE );
  750.     }
  751. }
  752.  
  753.  
  754. /************************************* CommonAction */
  755.  
  756. void    CommonAction( control, amount )
  757. ControlHandle    control;
  758. short            *amount;
  759. {
  760.     short        value, max;
  761.     
  762.     value = GetCtlValue( control );    /* get current value */
  763.     max = GetCtlMax( control );        /* and maximum value */
  764.     *amount = value - *amount;
  765.     if ( *amount < 0 )
  766.         *amount = 0;
  767.     else if ( *amount > max )
  768.         *amount = max;
  769.     SetCtlValue( control, *amount );
  770.     *amount = value - *amount;        /* calculate the real change */
  771. }
  772.  
  773.  
  774. /************************************ DoActivate  */
  775.  
  776. void    DoActivate( window, becomingActive )
  777. WindowPtr    window;
  778. Boolean        becomingActive;
  779. {
  780.     FormPeek    form;
  781.     int            wType;
  782.     
  783.     wType = WindowType( window );
  784.     
  785.     if ( wType == FORM_WINDOW )
  786.     {
  787.         form = (FormPeek)window;
  788.         if ( becomingActive )
  789.         {
  790.             SetPort( window );
  791.             if ( form->curTE == form->miscTE )
  792.                 TurnOnTextArea( form, TE_MISC_AREA );
  793.             else
  794.                 TurnOnTextArea( form, TE_NAME_AREA );
  795.             HiliteControl( form->vScroll, 0 );
  796.         }
  797.         else
  798.         {
  799.             if ( form->curTE == form->miscTE )
  800.                 TurnOffTextArea( form, TE_MISC_AREA );
  801.             else
  802.                 TurnOffTextArea( form, TE_NAME_AREA );
  803.             HiliteControl( form->vScroll, 255 );
  804.         }
  805.     }
  806. }
  807.  
  808.  
  809. /******************************** AdjustCursor *********/
  810.  
  811. void    AdjustCursor( mouse, region )
  812. Point        mouse;
  813. RgnHandle    region;
  814. {
  815.     WindowPtr        window;
  816.     RgnHandle        arrowRgn, iBeamRgn, tempRgn;
  817.     Rect            tempRect;
  818.     int                wType;
  819.     GrafPtr            oldPort;
  820.         
  821.     window = FrontWindow();
  822.     wType = WindowType( window );
  823.     
  824.     if ( gInBackground || ( wType != FORM_WINDOW ) )
  825.     {
  826.         SetCursor( &arrow );
  827.         return;
  828.     }
  829.         
  830.     GetPort( &oldPort );
  831.     SetPort( window );
  832.     
  833.     arrowRgn = NewRgn();
  834.     iBeamRgn = NewRgn();
  835.     tempRgn = NewRgn();
  836.     
  837.     SetRectRgn( arrowRgn, -32700, -32700, 32700, 32700 );
  838.     
  839.     tempRect = gNameRect;
  840.     LocalToGlobal( &TopLeft(tempRect) );
  841.     LocalToGlobal( &BotRight(tempRect) );
  842.     RectRgn( tempRgn, &tempRect );
  843.     UnionRgn( iBeamRgn, tempRgn, iBeamRgn );
  844.     
  845.     tempRect = gMiscRect;
  846.     LocalToGlobal( &TopLeft(tempRect) );
  847.     LocalToGlobal( &BotRight(tempRect) );
  848.     RectRgn( tempRgn, &tempRect );
  849.     UnionRgn( iBeamRgn, tempRgn, iBeamRgn );
  850.     
  851.     DiffRgn( arrowRgn, iBeamRgn, arrowRgn );
  852.     
  853.     if ( PtInRgn( mouse, iBeamRgn ) )
  854.     {
  855.         SetCursor( *GetCursor( iBeamCursor ) );
  856.         CopyRgn( iBeamRgn, region );
  857.     }
  858.     else
  859.     {
  860.         SetCursor( &arrow );
  861.         CopyRgn( arrowRgn, region );
  862.     }
  863.     DisposeRgn( arrowRgn );
  864.     DisposeRgn( iBeamRgn );
  865.     DisposeRgn( tempRgn );
  866.         
  867.     SetPort( oldPort );
  868. }
  869.  
  870.  
  871. /************************************ DoUpdate  */
  872.  
  873. void    DoUpdate( window )
  874. WindowPtr    window;
  875. {
  876.     FormPeek    form;
  877.     int            wType;
  878.     GrafPtr        oldPort;
  879.     
  880.     GetPort( &oldPort );
  881.     SetPort( window );
  882.     
  883.     wType = WindowType( window );
  884.     
  885.     if ( wType == FORM_WINDOW )
  886.     {
  887.         BeginUpdate( window );
  888.         EraseRect( &window->portRect );
  889.         DrawForm( window );
  890.         EndUpdate( window );
  891.     }
  892.     
  893.     SetPort( oldPort );
  894. }
  895.  
  896.  
  897. /************************************ DrawForm  */
  898.  
  899. void    DrawForm( window )
  900. WindowPtr    window;
  901. {
  902.     FrameRect( &gNameRect );
  903.     FrameRect( &gMiscRect );
  904.     DrawControls( window );
  905.     
  906.     TextFont( geneva );
  907.     TextFace( bold );
  908.     
  909.     MoveTo( gNameRect.left - 34, gNameRect.top + 12 );
  910.     DrawString( "\pName" );
  911.     MoveTo( gMiscRect.left - 34, gMiscRect.top + 12 );
  912.     DrawString( "\pMisc." );
  913.     
  914.     TextFont( monaco );
  915.     TextFace( 0 );
  916.     
  917.     TEUpdate( &window->portRect, ((FormPeek)window)->nameTE );
  918.     TEUpdate( &window->portRect, ((FormPeek)window)->miscTE );
  919. }
  920.  
  921.  
  922. /************************************ CreateWindow  */
  923.  
  924. void    CreateWindow()
  925. {
  926.     WindowPtr    theNewestWindow;
  927.     Ptr            wStorage;
  928.     FormPeek    form;
  929.     
  930.     wStorage = NewPtr( sizeof(FormRecord) );
  931.     
  932.     if ( ( theNewestWindow = GetNewWindow( BASE_RES_ID, wStorage,
  933.                                 MOVE_TO_FRONT ) ) == NIL_POINTER )
  934.         ErrorHandler( NO_WIND );
  935.     if ( ( (screenBits.bounds.right - gNewWindowLeft) < DRAG_THRESHOLD ) ||
  936.          ( ( screenBits.bounds.bottom - gNewWindowTop) < DRAG_THRESHOLD ) )
  937.     {
  938.         gNewWindowLeft = WINDOW_HOME_LEFT;
  939.         gNewWindowTop = WINDOW_HOME_TOP;
  940.     }
  941.     
  942.     MoveWindow( theNewestWindow, gNewWindowLeft, gNewWindowTop, LEAVE_WHERE_IT_IS );
  943.     gNewWindowLeft += NEW_WINDOW_OFFSET;
  944.     gNewWindowTop += NEW_WINDOW_OFFSET;
  945.     
  946.     form = (FormPeek)theNewestWindow;
  947.     form->wType = FORM_WINDOW;
  948.     
  949.     form->vScroll = NewControl( theNewestWindow, &gScrollBarRect, NIL_STRING,
  950.             VISIBLE, 0, 0, 0, scrollBarProc, 0L);
  951.     
  952.     ShowWindow( theNewestWindow );
  953.     SetPort( theNewestWindow );
  954.     TextFont( monaco );
  955.     TextFace( 0 );
  956.     TextSize( 9 );
  957.     StartTextEdit( form );
  958. }
  959.  
  960.  
  961. /******************************** StartTextEdit *********/
  962.  
  963. void    StartTextEdit( form )
  964. FormPeek    form;
  965. {
  966.     Rect    r;
  967.     
  968.     r = gNameRect;
  969.     InsetRect( &r, 2, 2 );
  970.     form->nameTE = TENew( &r, &r );
  971.     
  972.     r = gMiscRect;
  973.     InsetRect( &r, 2, 2 );
  974.     form->miscTE = TENew( &r, &r );
  975.     SetClikLoop( NewClikLoop, form->miscTE );
  976.     
  977.     TEAutoView( TRUE, form->miscTE );
  978.     
  979.     form->curTE = form->nameTE;
  980. }
  981.  
  982.  
  983. /******************************** NewClikLoop *********/
  984.  
  985. pascal Boolean    NewClikLoop()
  986. {
  987.     WindowPtr    window;
  988.     FormPeek    form;
  989.     TEHandle    te;
  990.     Rect        tempRect;
  991.     Point        mouse;
  992.     GrafPtr        oldPort;
  993.     short            amount;
  994.     RgnHandle    oldClip;
  995.     
  996.     window = FrontWindow();
  997.     if ( WindowType( window ) != FORM_WINDOW )
  998.         return( FALSE );
  999.         
  1000.     form = (FormPeek)window;
  1001.     te = form->curTE;
  1002.     
  1003.     GetPort( &oldPort );
  1004.     SetPort( window );
  1005.     oldClip = NewRgn();
  1006.     GetClip( oldClip );
  1007.     
  1008.     SetRect( &tempRect, -32767, -32767, 32767, 32767 );
  1009.     ClipRect( &tempRect );
  1010.     
  1011.     GetMouse( &mouse );
  1012.     
  1013.     if ( mouse.v < gMiscRect.top )
  1014.     {
  1015.         amount = 1;
  1016.         CommonAction( form->vScroll, &amount );
  1017.         if ( amount != 0 )
  1018.             TEScroll( 0, amount * ((*te)->lineHeight), te );
  1019.     }
  1020.     else if ( mouse.v > gMiscRect.bottom )
  1021.     {
  1022.         amount = -1;
  1023.         CommonAction( form->vScroll, &amount );
  1024.         if ( amount != 0 )
  1025.             TEScroll( 0, amount * ((*te)->lineHeight), te );
  1026.     }
  1027.     
  1028.     SetClip( oldClip );
  1029.     DisposeRgn( oldClip );
  1030.     SetPort( oldPort );
  1031.     return( TRUE );
  1032. }
  1033.  
  1034.  
  1035. /******************************** SwitchToNewArea *********/
  1036.  
  1037. void    SwitchToNewArea( form, newArea )
  1038. FormPeek    form;
  1039. int            newArea;
  1040. {
  1041.     if ( form->curTE == form->nameTE )
  1042.     {
  1043.         TurnOffTextArea( form, TE_NAME_AREA );
  1044.         TurnOnTextArea( form, TE_MISC_AREA );
  1045.     }
  1046.     else
  1047.     {
  1048.         TurnOffTextArea( form, TE_MISC_AREA );
  1049.         TurnOnTextArea( form, TE_NAME_AREA );
  1050.     }
  1051. }
  1052.  
  1053.  
  1054. /******************************** TurnOnTextArea *********/
  1055.  
  1056. void    TurnOnTextArea( form, whichArea )
  1057. FormPeek    form;
  1058. int            whichArea;
  1059. {
  1060.     TEPtr                    te;
  1061.     
  1062.     if ( whichArea == TE_MISC_AREA )
  1063.     {
  1064.         te = *form->miscTE;
  1065.         te->viewRect.bottom = (((te->viewRect.bottom - te->viewRect.top) / te->lineHeight)
  1066.                             * te->lineHeight) + te->viewRect.top;
  1067.         te->destRect.bottom = te->viewRect.bottom;
  1068.         AdjustScrollBar( form );
  1069.         form->curTE = form->miscTE;
  1070.     }
  1071.     else
  1072.         form->curTE = form->nameTE;
  1073.         
  1074.     TEActivate( form->curTE );
  1075. }
  1076.  
  1077.  
  1078. /******************************** TurnOffTextArea *********/
  1079.  
  1080. void    TurnOffTextArea( form, whichArea )
  1081. FormPeek    form;
  1082. int            whichArea;
  1083. {    
  1084.     if ( whichArea == TE_MISC_AREA )
  1085.         TEDeactivate( form->miscTE );
  1086.     else
  1087.         TEDeactivate( form->nameTE );
  1088. }
  1089.  
  1090.  
  1091. /******************************** AdjustScrollBar *********/
  1092.  
  1093. void    AdjustScrollBar( form )
  1094. FormPeek    form;
  1095. {
  1096.     short        value, lines, max;
  1097.     short        oldValue, oldMax;
  1098.     TEPtr        te;
  1099.     
  1100.     oldValue = GetCtlValue( form->vScroll );
  1101.     oldMax = GetCtlMax( form->vScroll );
  1102.     te = *(form->miscTE);
  1103.     
  1104.     lines = te->nLines;
  1105.     if ( *(*te->hText + te->teLength - 1) == TE_CARRIAGE_RETURN )
  1106.         lines += 1;
  1107.     max = lines - ((te->viewRect.bottom - te->viewRect.top) /
  1108.             te->lineHeight);
  1109.     
  1110.     if ( max < 0 ) max = 0;
  1111.     SetCtlMax( form->vScroll, max);
  1112.     
  1113.     te = *(form->miscTE);
  1114.     value = (te->viewRect.top - te->destRect.top) / te->lineHeight;
  1115.     
  1116.     if ( value < 0 ) value = 0;
  1117.     else if ( value >  max ) value = max;
  1118.     
  1119.     SetCtlValue( form->vScroll, value);
  1120.     
  1121.     TEScroll( 0, (te->viewRect.top - te->destRect.top) -
  1122.                 (GetCtlValue( form->vScroll ) * te->lineHeight), form->miscTE );
  1123. }
  1124.  
  1125.  
  1126. /******************************** ErrorHandler *********/
  1127.  
  1128. void    ErrorHandler( stringNum )
  1129. int    stringNum;
  1130. {
  1131.     StringHandle    errorStringH;
  1132.     
  1133.     if ( ( errorStringH = GetString( stringNum ) ) == NIL_POINTER )
  1134.         ParamText( HOPELESSLY_FATAL_ERROR, NIL_STRING, NIL_STRING, NIL_STRING );
  1135.     else
  1136.     {
  1137.         HLock( (Handle)errorStringH );
  1138.         ParamText( *errorStringH, NIL_STRING, NIL_STRING, NIL_STRING );
  1139.         HUnlock( (Handle)errorStringH );
  1140.     }
  1141.     StopAlert( ERROR_ALERT_ID, NIL_POINTER );
  1142.     ExitToShell();
  1143. }